package com.bsj.pay.util.platform.wsgw.sm;

public class SM3Utils
{
    private static final int BLOCK_LENGTH = 64;
    private static final int BUFFER_LENGTH = 64;
    private static final int BYTE_LENGTH = 32;
    private byte[] V;
    private int cntBlock;
    private byte[] xBuf;
    private int xBufOff;
    
    public SM3Utils() {
        this.xBuf = new byte[64];
        this.V = SM3.iv.clone();
        this.cntBlock = 0;
    }
    
    public SM3Utils(final SM3Utils sm3Utils) {
        this.xBuf = new byte[64];
        this.V = SM3.iv.clone();
        this.cntBlock = 0;
        System.arraycopy(sm3Utils.xBuf, 0, this.xBuf, 0, sm3Utils.xBuf.length);
        this.xBufOff = sm3Utils.xBufOff;
        System.arraycopy(sm3Utils.V, 0, this.V, 0, sm3Utils.V.length);
    }
    
    private byte[] doFinal() {
        final byte[] array = new byte[64];
        final byte[] array2 = new byte[this.xBufOff];
        byte[] v;
        if (this.xBufOff == 0) {
            v = null;
        }
        else {
            System.arraycopy(this.xBuf, 0, array2, 0, array2.length);
            final byte[] padding = SM3.padding(array2, this.cntBlock);
            for (int i = 0; i < padding.length; i += 64) {
                System.arraycopy(padding, i, array, 0, array.length);
                this.doHash(array);
            }
            v = this.V;
        }
        return v;
    }
    
    private void doHash(final byte[] array) {
        System.arraycopy(SM3.CF(this.V, array), 0, this.V, 0, this.V.length);
        ++this.cntBlock;
    }
    
    private void doUpdate() {
        final byte[] array = new byte[64];
        for (int i = 0; i < 64; i += 64) {
            System.arraycopy(this.xBuf, i, array, 0, array.length);
            this.doHash(array);
        }
        this.xBufOff = 0;
    }
    
    public byte[] SG_SM3Final() {
        return this.doFinal();
    }
    
    public void SG_SM3UpDate(final byte[] array) {
        this.update(array, 0, 0);
    }
    
    protected int doFinal(final byte[] array, final int n) {
        final byte[] doFinal = this.doFinal();
        System.arraycopy(doFinal, 0, array, 0, doFinal.length);
        return 32;
    }
    
    protected int getDigestSize() {
        return 32;
    }
    
    protected void reset() {
        this.xBufOff = 0;
        this.cntBlock = 0;
        this.V = SM3.iv.clone();
    }
    
    public byte[] sign(byte[] array) {
        this.update(array, 0, array.length);
        array = new byte[32];
        this.doFinal(array, 0);
        return array;
    }
    
    protected void update(final byte b) {
        this.update(new byte[] { b }, 0, 1);
    }
    
    protected void update(final byte[] array, int n, int length) {
        final int n2 = 64 - this.xBufOff;
        length = array.length;
        if (array != null && length > 0) {
            int n3 = n;
            int n4;
            if (n2 < (n4 = length)) {
                System.arraycopy(array, n, this.xBuf, this.xBufOff, n2);
                length -= n2;
                final int n5 = n + n2;
                this.doUpdate();
                n = length;
                length = n5;
                while (true) {
                    n3 = length;
                    n4 = n;
                    if (n <= 64) {
                        break;
                    }
                    System.arraycopy(array, length, this.xBuf, 0, 64);
                    n -= 64;
                    length += 64;
                    this.doUpdate();
                }
            }
            System.arraycopy(array, n3, this.xBuf, this.xBufOff, n4);
            this.xBufOff += n4;
        }
    }
}
